package com.tma.mobilechart.line;

import java.util.ArrayList;
import java.util.List;

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;

import android.content.Context;
import android.opengl.GLES10;
import android.opengl.GLSurfaceView;
import android.opengl.GLSurfaceView.Renderer;
import android.opengl.GLU;
import android.view.MotionEvent;

import com.tma.mobilechart.utilitys.ZoomMultitouch;


public class LineRender2D extends GLSurfaceView implements Renderer {
	
	private LineAxisCoord2D mAxis;
	//private Line mline;
    private float z = -5.0f;			//Depth Into The Screen
    
    static final int NONE = 0;
	static final int DRAG = 1;
	static final int ZOOM = 2;
	int mode = NONE;
	       
    private List<Line2D> mLine;
        
    private LineInputData mInputData;
    
    private int unitNumber = 0; // chu so lon nhat cua so nguyen
    private float xAxis = 1.25f;
	private float yAxis = 1.0f;
  	
	public LineRender2D(Context context, LineInputData mInputData)
	{	super(context);
		
		this.setRenderer(this);	
		
		this.mInputData = mInputData;
		
		float[] findMax;		
		findMax = new float[this.mInputData.getlData().size()];
		for(int i = 0; i < findMax.length; i++)
		{
			findMax[i] = findMaxIndex(this.mInputData.getlData().get(i).getlYValue());
		}
		
		this.mInputData.setMaxValueY(findMaxIndex(findMax));
		
		mLine = new ArrayList<Line2D>();
		for(int i = 0; i < mInputData.getlData().size(); i++)
		{
			Line2D _mline = new Line2D(this.mInputData, i, this.mInputData.getlData().get(i).getlColor());
			mLine.add(_mline);
		}		
		mAxis = new LineAxisCoord2D();
	}
	
	@Override
	public void onDrawFrame(GL10 gl) {
		// TODO Auto-generated method stub		
		gl.glClear(GLES10.GL_COLOR_BUFFER_BIT|GLES10.GL_DEPTH_BUFFER_BIT);		
		gl.glLoadIdentity();
		gl.glTranslatef(-0.5f, 0.0f, z);
		mAxis.draw(gl);
		
		// draw sub lines
		long maxValue = (long) mInputData.getMaxValueY();
		int numberCount = 0;  //so chu so cua maxValue
		long rootNumber = 1;  	//gia tri goc ca so MaxValue dung chia
		float eachSegment = 0; 		//gia tri moi doan nho tren yAxis - fai khoi tao gia tri
		long rootMax;			// gia tri max tren yAxis 
		float jumpValue = 1;		//buoc nhay- giua 2 gia tri lien tiep tren yAxis - fai khoi tao gia tri
		while(maxValue != 0)
		{
			unitNumber = (int) maxValue%10;
			maxValue = maxValue/10;
			numberCount++;
		}
		maxValue = (long) mInputData.getMaxValueY();
		for(int i = 1; i < numberCount; i++)
			rootNumber *= 10;
		if(maxValue%rootNumber != 0)
		{
			unitNumber += 1;
		}
		switch(unitNumber)
		{
			case 4: unitNumber = 5; break;
			case 6: unitNumber = 8; break;
			case 7: unitNumber = 8; break;
			case 8: unitNumber = 10; break;
			case 9: unitNumber = 10; break;
		}
		
		switch(unitNumber)			//sai th nhap 1,2
		{
			case 1:
				eachSegment = (float) yAxis/5;
				rootMax = rootNumber;
				jumpValue = rootMax/5;
				gl.glPushMatrix();

				for(int i = 1; i <= 5; i++)
				{
					gl.glTranslatef(0.0f, eachSegment, 0.0f);
					mAxis.drawSubLine(gl);
					// addTextYAxis(Float.toString(i*jumpValue),gl);
				}
				gl.glPopMatrix();
				break;
			case 10:
				eachSegment = (float) yAxis/5;
				rootMax = 10*rootNumber;
				jumpValue = rootMax/5;
				gl.glPushMatrix();
				for(int i = 1; i <= 5; i++)
				{
					gl.glTranslatef(0.0f, eachSegment, 0.0f);
					mAxis.drawSubLine(gl);
					// addTextYAxis(Float.toString(i*jumpValue),gl);
				}
				gl.glPopMatrix();
				break;
			case 2:
				eachSegment = (float) yAxis/4;
				rootMax = 2*rootNumber;
				jumpValue = rootMax/4;
				gl.glPushMatrix();
				for(int i = 1; i <= 4; i++)
				{
					gl.glTranslatef(0.0f, eachSegment, 0.0f);
					mAxis.drawSubLine(gl);
					// addTextYAxis(Float.toString(i*jumpValue),gl);
				}
				gl.glPopMatrix();
				break;
			case 3:
				eachSegment = (float) yAxis/5;
				rootMax = 3*rootNumber;
				jumpValue = rootMax/5;
				gl.glPushMatrix();
				for(int i = 1; i <= 5; i++)
				{
					gl.glTranslatef(0.0f, eachSegment, 0.0f);
					mAxis.drawSubLine(gl);
					//ghi gia tri yAxis tuong ung vao
					// gia tri maxValue = 3*rootNumber;
					// addTextYAxis(Float.toString(i*jumpValue),gl);
				}
				gl.glPopMatrix();
				break;
			case 5:
				eachSegment = (float) yAxis/5;
				rootMax = 5*rootNumber;
				jumpValue = rootMax/5;
				gl.glPushMatrix();
				for(int i = 1; i <= 5; i++)
				{
					gl.glTranslatef(0.0f, eachSegment, 0.0f);
					mAxis.drawSubLine(gl);
					// addTextYAxis(Float.toString(i*jumpValue),gl);

				}
				gl.glPopMatrix();
				break;
			case 8:
				eachSegment= (float) yAxis/4;
				rootMax = 8*rootNumber;
				jumpValue = rootMax/4;
				gl.glPushMatrix();
				for(int i = 1; i <= 4; i++)
				{
					gl.glTranslatef(0.0f, eachSegment, 0.0f);
					mAxis.drawSubLine(gl);
					// addTextYAxis(Float.toString(i*jumpValue),gl);

				}
				gl.glPopMatrix();
				break;
		}
		
		// draw Lines
		gl.glLineWidth(3.0f);
		for(int i = 0; i < mLine.size(); i++)
		{
			mLine.get(i).draw(gl);
		}
		
		if (ZoomMultitouch.m_GestureMode == 2 && ZoomMultitouch.m_PinchFlag == 1) 
		{
			ZoomMultitouch.setClipping(gl, ZoomMultitouch.origwidth, ZoomMultitouch.origheight);
			ZoomMultitouch.m_PinchFlag = 0;
		}
				
	}
	
	@Override
	public void onSurfaceChanged(GL10 gl, int width, int height) {
		// TODO Auto-generated method stub
		if(height == 0) 
		{                       //Prevent A Divide By Zero By
			height = 1;                         //Making Height Equal One
		}
		gl.glViewport(0, 0, width, height);     //Reset The Current Viewport
		ZoomMultitouch.origwidth = width;
		ZoomMultitouch.origheight = height;
		gl.glMatrixMode(GL10.GL_PROJECTION);    //Select The Projection Matrix
		gl.glLoadIdentity();                    //Reset The Projection Matrix
		ZoomMultitouch.setClipping(gl, width, height);
		//Calculate The Aspect Ratio Of The Window
		GLU.gluPerspective(gl, 45.0f, (float)width / (float)height, 0.1f, 100.0f);
		gl.glMatrixMode(GL10.GL_MODELVIEW);     //Select The Modelview Matrix
		gl.glLoadIdentity();                    //Reset The Modelview Matrix

	}

	@Override
	public void onSurfaceCreated(GL10 gl, EGLConfig config) {
		// TODO Auto-generated method stub
		gl.glClearColor(0.1f, 0.5f, 0.5f, 0.5f);
		gl.glShadeModel(GL10.GL_SMOOTH); 			//Enable Smooth Shading
		gl.glClearColor(0.0f, 0.0f, 0.0f, 0.5f); 	//Black Background
		gl.glClearDepthf(1.0f); 					//Depth Buffer Setup
		gl.glEnable(GL10.GL_DEPTH_TEST); 			//Enables Depth Testing
		gl.glDepthFunc(GL10.GL_LEQUAL); 			//The Type Of Depth Testing To Do
		
		//Really Nice Perspective Calculations
		gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_NICEST); 
		
	}
	
	@Override		 
	public boolean onTouchEvent(MotionEvent ev) 
	{
			boolean retval = true;
			float x = ev.getX();
		    float y = ev.getY();
		    
		    float dx,dy;
			
			switch (ev.getAction() & MotionEvent.ACTION_MASK) 
			{
				case MotionEvent.ACTION_DOWN:
					mode = DRAG;
					break;
					
				case MotionEvent.ACTION_UP:
				case MotionEvent.ACTION_POINTER_UP:
					mode = NONE;
					ZoomMultitouch.m_LastTouchPoint.x = ev.getX();
					ZoomMultitouch.m_LastTouchPoint.y = ev.getY();
					break;
					
				case MotionEvent.ACTION_POINTER_DOWN:
					ZoomMultitouch.m_OldDist = ZoomMultitouch.spacing(ev);//distance
		
					ZoomMultitouch.midPoint(ZoomMultitouch.m_MidPoint, ev);//mid point
					mode = ZOOM;
					ZoomMultitouch.m_StartFOV = ZoomMultitouch.getFieldOfView();

					ZoomMultitouch.m_LastTouchPoint.x = ZoomMultitouch.m_MidPoint.x;
					ZoomMultitouch.m_LastTouchPoint.y = ZoomMultitouch.m_MidPoint.y;
					ZoomMultitouch.m_CurrentTouchPoint.x = ZoomMultitouch.m_MidPoint.x;
					ZoomMultitouch.m_CurrentTouchPoint.y = ZoomMultitouch.m_MidPoint.y;
					
					break;
					
				case MotionEvent.ACTION_MOVE:
					if (mode == DRAG) 
					{	
						retval = ZoomMultitouch.handleDragGesture(ev);
					} 
					else if (mode == ZOOM) 
					{
						retval = ZoomMultitouch.handlePinchGesture(ev);
					}
					requestRender();
					break;
			}
			return retval;
	}
		
	
	public float findMaxIndex(float[] array)
	{
		float result = 0;		
		result = array[0];
		for(int i = 0; i< array.length; i++)
		{
			if(result <= array[i])
			{
				result = array[i];
			}
		}
		return result;
	}
		
}